package com.lzyyj.gmis.base.service;

import com.lzyyj.gmis.base.model.IUser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

@Service("systemService")
public class SystemService implements ISystemService {

	private static final Log log = LogFactory.getLog(SystemService.class);

	private static ApplicationContext context;

	private static ApplicationContext useContext() throws Exception {
		if (context==null){
			throw new Exception("基础系统服务未曾启动，还未注入应用环境，请检查配置！");
		}
		return context;
	}

	/**
	 * 用于保存线程数据的对象，保存在同一线程中要用到的数据.
	 */
	private static final ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<Map<String, Object>>();

	/**
	 * 获得线程线程变量Map
	 * 
	 * @return 线程变量Map
	 * @param create
	 *            是否创建缺省值
	 */
	public Map<String, Object> getThreadLocalMap(boolean create) {
		Map<String, Object> map = threadLocal.get();
		if (map == null && create) {
			map = new HashMap<String, Object>();
			threadLocal.set(map);
		}
		return map;
	}

	/**
	 * 设置线程变量Map
	 * 
	 * @param map
	 *            线程变量Map
	 */
	public void setThreadLocalMap(Map<String, Object> map) {
		threadLocal.set(map);
	}

	/**
	 * 删除线程变量Map
	 */
	public void removeThreadLocalMap() {
		threadLocal.remove();
	}

	private Map<String, Map<String, Object>> sessionMap = null;

	private Map<Serializable, IUser<Serializable>> onlineUserMap = new HashMap<Serializable, IUser<Serializable>>();
	
	private IMenuService<? extends Serializable> menuService;
	
	private IPurviewService<? extends Serializable> purviewService;
	
	private IRoleService<? extends Serializable> roleService;
	
	private IOrganizationService<? extends Serializable> organizationService;
	
	private IDepartmentService<? extends Serializable> departmentService;

	/**
	 * 系统停止
	 * @throws Exception 
	 */
	@Override
	public void contextDestroyed() throws Exception {
		log.debug("系统关闭，当前在线节点数：" + sessionMap.size() + " 当前在线人数：" + onlineUserMap.size());
		sessionMap.clear();
		onlineUserMap.clear();
		List<IModuleService> moduleServiceList = findService(IModuleService.class);
		if (moduleServiceList != null) {
			for (IModuleService module : moduleServiceList) {
				module.stop();
			}
		}
	}

	/**
	 * 系统启动，初始化运行环境
	 * @throws Exception 
	 */
	@Override
	public void contextInitialized(ApplicationContext context) throws Exception {
		SystemService.context = context;

		if (sessionMap == null) {
			sessionMap = new HashMap<String, Map<String, Object>>();
			log.info("系统正在启动！");
		} else {
			sessionMap.clear();
			log.info("系统正在重新启动！");
		}
		if (onlineUserMap == null) {
			sessionMap = new HashMap<String, Map<String, Object>>();
		}
		log.debug("系统启动，当前在线节点数：" + sessionMap.size() + " 当前在线人数：" + onlineUserMap.size());
		// 遍历需要初始化的功能模块
		List<IModuleService> moduleServiceList = findService(IModuleService.class);
		if (moduleServiceList != null) {
			for (IModuleService module : moduleServiceList) {
				module.start();
			}
		}
		Map<String, IBaseService> serviceMap = context.getBeansOfType(IBaseService.class);
		// 检查需要初始化的服务模块
		for(Entry<String, IBaseService> entry: serviceMap.entrySet()){
			if (entry.getValue() instanceof IInitNeeded){
				IInitNeeded service = (IInitNeeded)(entry.getValue());
				service.init();
			}
		}
	}

	@Override
	public IMenuService<? extends Serializable> getMenuService() {
		if (menuService==null&&context!=null){
			menuService = context.getBean(IMenuService.class);
		}
		return menuService;
	}

	@Override
	public void setMenuService(IMenuService<? extends Serializable> menuService) {
		this.menuService = menuService;
	}

	@Override
	public IPurviewService<? extends Serializable> getPurviewService() {
		if (purviewService==null&&context!=null&&context.getBeansOfType(IPurviewService.class).size()>0){
			purviewService = context.getBean(IPurviewService.class);
		}
		return purviewService;
	}

	@Override
	public void setPurviewService(IPurviewService<? extends Serializable> purviewService) {
		this.purviewService = purviewService;
	}

	@Override
	public IRoleService<? extends Serializable> getRoleService() {
		if (roleService==null&&context!=null){
			roleService = context.getBean(IRoleService.class);
		}
		return roleService;
	}

	@Override
	public void setRoleService(IRoleService<? extends Serializable> roleService) {
		this.roleService = roleService;
	}
  
	@Override
	public IOrganizationService<? extends Serializable> getOrganizationService() {
		if (organizationService==null&&context!=null){
			organizationService = context.getBean(IOrganizationService.class);
		}
		return organizationService;
	}

	@Override
	public void setOrganizationService(IOrganizationService<? extends Serializable> organizationService) {
		this.organizationService = organizationService;
	}

	@Override
	public IDepartmentService<? extends Serializable> getDepartmentService() {
		if (departmentService==null&&context!=null){
			departmentService = context.getBean(IDepartmentService.class);
		}
		return departmentService;
	}

	@Override
	public void setDepartmentService(IDepartmentService<? extends Serializable> departmentService) {
		this.departmentService = departmentService;
	}

	@Override
	public void sessionCreated(String sessionId, Map<String, Object> sessionMap) {
		this.sessionMap.put(sessionId, sessionMap);
	}

	@Override
	public void logined(IUser<Serializable> user) {
		onlineUserMap.put(user.getId(), user);
		log.info("用户 " + user.getLoginName() + "[" + user.getLoginName() + "] 已经登录！");
	}

	@Override
	public void logouted(IUser<Serializable> user) {
		// TODO Auto-generated method stub

	}

	/**
	 * 获取在线人数
	 * 
	 * @return
	 */
	@Override
	public int getOnLineCount() {
		return sessionMap.size();
	}

	public static <T> T getBean(Class<T> clazz) {
		T result = null;
		
		if (context!=null){
			context.getBean(clazz);
		}
		
		return result;
	}
	
	@Override
	public <T> List<T> findService(Class<T> clazz) {
		List<T> list = new ArrayList<T>();

		if (context!=null){
			Map<String, T> li = context.getBeansOfType(clazz);
			for (Entry<String, T> entry : li.entrySet()) {
				list.add(entry.getValue());
			}
		}

		return list;
	}

	@Override
	public <T> Map<String, T> getServiceMap(Class<T> clazz) {
		Map<String, T> list = context.getBeansOfType(clazz);

		return list;
	}
}
